#!/usr/bin/env python
# -*- coding: utf-8 -*-
from sca import SCA
from sdt import SDT
from SVR import SVR
import random
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from Utils.util import EvalR

def compress(s, x, y):
	"""
	使用SDT进行单个数据的筛选，进行压缩
	:return:
	"""
	x_data = []
	y_data = []
	for i in range(len(x)):
		xi = x[i]
		yi = y[i]
		dx, dy = s.check((xi, yi))
		if dx != None and dy != None:
			x_data.append(dx)
			y_data.append(dy)
			#print("需要的存储数据点为(%.2f,%.2f)" % (dx, dy))
		else:
			pass
	return x_data, y_data

def compress_data_plot(x, y, scale, flag, verbose):
	"""
	人为数据集的数据转换及可视化
	:param flag: sdt or sca
	:return:
	"""
	#压缩算法
	if flag == 'sdt':
		deltaE = 0.005 * scale
		xx = [t for t in x]
		yy = [t + (([-1, 1] + [0] * 98)[random.randint(0, 100) % 100]) * scale * min(0.02, random.random()) for t in y]
		s = SDT(deltaE)
		x = xx
		y = yy
		cx, cy = compress(s, x, y)
		rate = len(cx)/len(x)
		print('旋转门算法的压缩率为：{:.2f}'.format(rate))
	elif flag == 'sca':  # 0.6/700
		delta = 50
		numb = 6
		x = np.array(x).reshape(-1, 1)
		y = np.array(y).reshape(-1, 1)
		data1 = np.hstack((x, y))
		s = SCA(delta, numb)
		compress_data, index = s.compress_data(data1)
		cx, cy = x[index, :], y[index, :]
		rate = np.shape(cx)[0]/np.shape(x)[0]
		print('一种稀疏表示的压缩算法的压缩率为：{:.2f}'.format(rate))
	else:
		raise ValueError("the flag must be sdt or sca")
	# 可视化展示
	font = {'family': 'serif',
			'color': 'darkred',
			'weight': 'normal',
			'size': 16,
			}
	plt.rcParams['font.sans-serif'] = ['SimHei']
	plt.rcParams['axes.unicode_minus'] = False
	if flag == 'sdt':
		plt.title('旋转门算法结果可视化图')
	elif flag == 'sca':
		plt.title('一种稀疏表示的压缩算法结果可视化图')
	plt.grid(True, linewidth="0.4")
	plt.plot(x, y, 'o', color='blue', label='true')
	plt.xlabel("x", fontdict=font)
	plt.ylabel("y", fontdict=font)
	plt.plot(cx, cy, ">", color='red', label='compress')
	plt.legend(('原始数据(全集)', '压缩后数据(子集)'), loc='upper right')
	if flag == 'sdt':
		plt.savefig('./img/{value1}{value2}.jpg'.format(value1=verbose, value2='旋转门算法'))
	elif flag == 'sca':
		plt.savefig('./img/{value1}{value2}.jpg'.format(value1=verbose, value2='一种稀疏表示的压缩算法'))

	return cx, cy


def data_model_predict(x, y, verbose):
	"""
	用支持向量回归机对数据集进行验证
	:return:
	"""
	min_value = 1000
	optimal_gamma = []
	X = np.array(x).reshape(-1, 1)
	Y = np.array(y).reshape(-1, 1)
	train_x, test_x, train_y, test_y = train_test_split(X, Y, test_size=0.2, random_state=42)
	gammas = [0.001, 0.01, 0.1, 1, 10, 100]
	for gamma in gammas:
		model = SVR(kernel='rbf', gamma=gamma, debug=False)
		model.fit(train_x, train_y.T[0])
		y_pred = model.predict(test_x)
		value = EvalR.RMSE(y_pred, test_y)
		if value < min_value:
			min_value = value
			optimal_gamma.append(gamma)
	if optimal_gamma is None:
		raise ValueError('this dataset can not fit the svr')
	print('{value}电厂模型最佳的参数：gamma={value1}, 模型最佳的RMSE为：{value2}'.format(value=verbose, value1=optimal_gamma[-1], value2=min_value))

	return optimal_gamma[-1], min_value




